﻿using System;
using System.Collections.Generic;
using System.Linq;
using Joel.Vishnu.Modelo.Entidades;
using Joel.Vishnu.Modelo.Enumeradores;
using Joel.Vishnu.Presentacion.Vistas;
using Joel.Vishnu.Presentacion;
using Joel.Vishnu.Consola;
using Joel.Vishnu.Modelo.Objetos;

namespace Joel.Vishnu.Consola
{
    public class Clientes : Base, IClientes
    {
        #region Constructores

        public Clientes()
            : base()
        {
            presentador = new ClientesPresentador(this);
            listaClientes = new List<Cliente>();
            listaBarrios = new List<Barrio>();
            validador = String.Empty;
        }

        #endregion

        #region Atributos

        private ClientesPresentador presentador;
        private Int32 clienteId;
        private String nombre;
        private String apellido;
        private Int32 dni;
        private DateTime fechaCumpleanos;
        private Int32 generoId;
        private String email;
        private String telefono;
        private String direccion;
        private Int32 barrioId;
        private List<Barrio> listaBarrios;
        private DateTime fechaPrimeraCompra;
        private EnumEstado estado;
        private List<Cliente> listaClientes;
        private String validador;

        #endregion

        #region Propiedades

        public Int32 ClienteId
        {
            get { return clienteId; }
        }

        public String Nombre
        {
            get { return nombre; }
        }

        public String Apellido
        {
            get { return apellido; }
        }

        public Int32 Dni
        {
            get { return dni; }
        }

        public DateTime FechaCumpleanos
        {
            get { return fechaCumpleanos; }
        }

        public Int32 GeneroId
        {
            get { return generoId; }
        }

        public String Email
        {
            get { return email; }
        }

        public String Telefono
        {
            get { return telefono; }
        }

        public String Direccion
        {
            get { return direccion; }
        }

        public Int32 BarrioId
        {
            get { return barrioId; }
        }

        public List<Barrio> ListaBarrios
        {
            set { listaBarrios = value; }
        }

        public DateTime FechaPrimeraCompra
        {
            get { return fechaPrimeraCompra; }
        }

        public EnumEstado Estado
        {
            get { return estado; }
        }

        public List<Cliente> ListaClientes
        {
            set { listaClientes = value; }
        }

        public Barrios Barrios
        {
            get { return new Barrios(); }
        }

        public Generos Generos
        {
            get { return new Generos(); }
        }

        #endregion

        #region Metodos

        public String Menu()
        {
            Console.Clear();
            Titulo("********** Clientes **********");
            MensajeInformativo("(1) Agregar");
            MensajeInformativo("(2) Modificar");
            MensajeInformativo("(3) Eliminar");
            MensajeInformativo("(4) Listado");
            Console.WriteLine();
            MensajeInformativo("(5) Barrios");
            Console.WriteLine();
            MensajeInformativo("(0) Menú principal");
            Console.WriteLine();
            MensajeInformativo("Presione el número de la opción deseada.");
            return Console.ReadKey().KeyChar.ToString();
        }

        public void Insertar()
        {
            try
            {
                Console.Clear();
                Cliente cliente = new Cliente();
                Titulo("********** Agregar cliente **********");
                MensajeInformativoSeguido("Nombre: ");
                nombre = Console.ReadLine();
                MensajeInformativoSeguido("Apellido: ");
                apellido = Console.ReadLine();
                MensajeInformativoSeguido("DNI: ");
                validador = Console.ReadLine();
                if (Validadores.ValidadorEnteros(validador) == false)
                    throw new Exception("Sólo puede ingresar números para el DNI.");
                if (validador.Length < 8 || validador.Length > 8)
                    throw new Exception("El DNI debe ser de 8 dígitos.");
                dni = Convert.ToInt32(validador);
                MensajeInformativoSeguido("Fecha de cumpleaños: ");
                validador = Console.ReadLine();
                if (Validadores.ValidadorFechas(validador) == false)
                    throw new Exception("La fecha de cumpleaños debe ser de formato MM/DD/AAAA.");
                fechaCumpleanos = Convert.ToDateTime(validador);
                Generos.MostrarGeneros();
                MensajeInformativoSeguido("Género Id: ");
                validador = Console.ReadLine();
                if (Validadores.ValidadorEnteros(validador) == false)
                    throw new Exception("El género Id debe ser un número entero.");
                generoId = Convert.ToInt32(validador);
                MensajeInformativoSeguido("Email: ");
                validador = Console.ReadLine();
                if (Validadores.ValidadorEmails(validador) == false)
                    throw new Exception("El email no posee un formato correcto.");
                email = validador;
                MensajeInformativoSeguido("Teléfono: ");
                validador = Console.ReadLine();
                validador = validador.Replace("(", "");//Estos reemplazos para  el Telefono se podrian hacer en el metodo de validacion.
                validador = validador.Replace(")", "");
                validador = validador.Replace("-", "");
                validador = validador.Replace(" ", "");
                if (Validadores.ValidadorTelefonos(validador) == false)
                    throw new Exception("El número de teléfono debe estar compuesto de números enteros.");
                telefono = validador;
                MensajeInformativoSeguido("Dirección: ");
                direccion = Console.ReadLine();
                Barrios.MostrarBarrios();
                MensajeInformativoSeguido("Barrio Id: ");
                validador = Console.ReadLine();
                if (Validadores.ValidadorEnteros(validador) == false)
                    throw new Exception("El barrio Id debe ser un número entero.");
                barrioId = Convert.ToInt32(validador);
                MensajeInformativoSeguido("Fecha de primera compra: ");
                validador = Console.ReadLine();
                if (Validadores.ValidadorFechas(validador) == false)
                    throw new Exception("La fecha de cumpleaños debe ser de formato MM/DD/AAAA.");
                fechaPrimeraCompra = Convert.ToDateTime(validador);
                estado = EnumEstado.NUEVO;
                presentador.Aceptar();
                Console.WriteLine();
                MensajeInformativo("Cliente ingresado.");
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                MensajeError(ex.Message);
            }
        }

        public void Modificar()
        {
            try
            {
                String textoIngresado = String.Empty;
                Cliente cliente = new Cliente();

                Console.Clear();
                Titulo("********** Modificar cliente **********");
                MostrarClientes();
                Console.WriteLine();
                MensajeInformativoSeguido("Seleccione Id: ");
                validador = Console.ReadLine();
                if (Validadores.ValidadorEnteros(validador) == false || listaClientes.Where(x => x.Id == Convert.ToInt32(validador)).FirstOrDefault() == null)
                    throw new Exception("Debe seleccionar un cliente de la lista.");
                clienteId = Convert.ToInt32(validador);
                if (clienteId == (Int32)EnumClientes.CLIENTE_POR_DEFECTO)
                    throw new Exception("No se puede modificar un cliente por defecto.");
                cliente = listaClientes.Where(x => x.Id == clienteId).FirstOrDefault();
                
                MensajeInformativoSeguido("Nombre: ");
                textoIngresado = Console.ReadLine();
                if (textoIngresado != "=")
                    nombre = textoIngresado;
                else
                    nombre = cliente.Nombre;

                MensajeInformativoSeguido("Apellido: ");
                textoIngresado = Console.ReadLine();
                if (textoIngresado != "=")
                    apellido = textoIngresado;
                else 
                    apellido = cliente.Apellido;
                MensajeInformativoSeguido("DNI: ");
                textoIngresado = Console.ReadLine();
                if (textoIngresado != "=")
                    dni = Convert.ToInt32(textoIngresado);
                else
                    dni = cliente.Dni;

                MensajeInformativoSeguido("Fecha cumpleanos: ");
                textoIngresado = Console.ReadLine();
                if (textoIngresado != "=")
                    fechaCumpleanos = Convert.ToDateTime(textoIngresado);
                else
                    fechaCumpleanos = cliente.FechaCumpleanos;

                Generos.MostrarGeneros();
                MensajeInformativoSeguido("Genero Id: ");
                textoIngresado = Console.ReadLine();
                if (textoIngresado != "=")
                    generoId = Convert.ToInt32(textoIngresado);
                else
                    generoId = cliente.Genero.Id;

                MensajeInformativoSeguido("Email: ");
                textoIngresado = Console.ReadLine();
                if (textoIngresado != "=")
                    email = textoIngresado;
                else
                    email = cliente.Email;

                MensajeInformativoSeguido("Telefono: ");
                textoIngresado = Console.ReadLine();
                if (textoIngresado != "=")
                    telefono = textoIngresado;
                else
                    telefono = cliente.Telefono;

                MensajeInformativoSeguido("Direccion: ");
                textoIngresado = Console.ReadLine();
                if (textoIngresado != "=")
                    direccion = textoIngresado;
                else
                    direccion = cliente.Direccion;

                Barrios.MostrarBarrios();
                Console.WriteLine();
                MensajeInformativoSeguido("Barrio Id: ");
                textoIngresado = Console.ReadLine();
                if (textoIngresado != "=")
                    barrioId = Convert.ToInt32(textoIngresado);
                else
                    barrioId = cliente.Barrio.Id;

                MensajeInformativoSeguido("Fecha primera compra: ");
                textoIngresado = Console.ReadLine();
                if (textoIngresado != "=")
                    fechaPrimeraCompra = Convert.ToDateTime(textoIngresado);
                else
                    fechaPrimeraCompra = cliente.FechaPrimeraCompra;

                estado = EnumEstado.MODIFICAR;
                presentador.Aceptar();
                Console.WriteLine();
                MensajeInformativo("Cliente modificado.");
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                MensajeError(ex.Message);
            }
        }

        public void Eliminar()
        {
            try
            {
                Console.Clear();
                Titulo("********** Eliminar cliente **********");
                MostrarClientes();
                MensajeInformativoSeguido("Seleccione Id: ");
                validador = Console.ReadLine();
                if (Validadores.ValidadorEnteros(validador) == false || listaClientes.Where(x => x.Id == Convert.ToInt32(validador)).FirstOrDefault() == null)
                    throw new Exception("Debe seleccionar un cliente de la lista.");
                clienteId = Convert.ToInt32(validador);
                if (clienteId == (Int32)EnumClientes.CLIENTE_POR_DEFECTO)
                    throw new Exception("No se puede eliminar un cliente por defecto.");

                presentador.Eliminar();
                Console.WriteLine();
                MensajeInformativoSeguido("Cliente eliminado.");
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                MensajeError(ex.Message);
            }
        }

        public void Listado()
        {
            Console.Clear();
            Titulo("********** Listado de clientes **********");
            MostrarClientes();
            Console.ReadKey();
        }

        public void MostrarClientes()
        {
            MensajeInformativo(String.Format("{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10}",
                ArmarLineaInversa("Id", 3),
                ArmarLinea("Apellido", 15),
                ArmarLinea("Nombre", 16),
                ArmarLinea("DNI", 9),
                ArmarLinea("Cumpleaños", 10),
                ArmarLinea("Género", 9),
                ArmarLinea("Email", 30),
                ArmarLinea("Teléfono", 16),
                ArmarLinea("Dirección", 20),
                ArmarLinea("Barrio", 15),
                ArmarLinea("Primera compra", 14)));
            presentador.ActualizarClientes();
            foreach (var item in listaClientes)
                Console.WriteLine(String.Format("{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10}",
                    ArmarLineaInversa(Convert.ToString(item.Id), 3),
                    ArmarLinea(item.Apellido, 15),
                    ArmarLinea(item.Nombre, 16),
                    ArmarLinea(Convert.ToString(item.Dni), 9),
                    ArmarLineaInversa(item.FechaCumpleanos.ToString("d"), 10),
                    ArmarLinea(item.Genero.Nombre, 9),
                    ArmarLinea(item.Email, 30),
                    ArmarLinea(item.Telefono, 16),
                    ArmarLinea(item.Direccion, 20),
                    ArmarLinea(item.Barrio.Nombre, 15),
                    ArmarLineaInversa(item.FechaPrimeraCompra.Date.ToString("d"), 14)));
        }

        #endregion
    }
}
